<template>
	<div v-if="download">
		<el-popover placement="top" trigger="hover">
			<el-button type="primary" size="default" @click="onDownload" style="width: 100%">下载二维码</el-button>
			<template #reference>
				<el-image
					v-if="props.type === 'canvas' && props.preview"
					:src="imageUrl"
					:preview-teleported="true"
					:preview-src-list="[imageUrl]"
				/>
				<div v-else id="qr-code" ref="qrCodeRef"></div>
			</template>
		</el-popover>
	</div>
	<div v-else>
		<el-image
			v-if="props.type === 'canvas' && props.preview"
			:src="imageUrl"
			:preview-teleported="true"
			:preview-src-list="[imageUrl]"
		/>
		<div v-else id="qr-code" ref="qrCodeRef"></div>
	</div>
</template>

<script setup lang="ts" name="QRCode">
import { ref, onMounted } from "vue";
import QRCodeStyling, { DrawType, FileExtension } from "qr-code-styling"; // https://github.com/kozakdenys/qr-code-styling

/* 使用示例 */
// <template v-slot:qr_no="{ scope }">
// 	 <QRCode
// 		 :value="scope.row.tex_no"
// 		 :width="135"
// 		 :height="135"
// 		 :download="true"
// 		 :download-options="{ name: scope.row.tex_no, extension: 'png' }"
// 	 />
// </template>

interface QRCodeProps {
	value: string;
	type?: DrawType;
	width?: number;
	height?: number;
	margin?: number;
	preview?: boolean; // 注：type 为 canvas 时，preview 才生效
	qrOptions?: any;
	dotsOptions?: any;
	cornersDotOptions?: any;
	cornersSquareOptions?: any;
	backgroundOptions?: any;
	image?: string;
	imageOptions?: any;
	fileExt?: FileExtension;
	download?: boolean;
	downloadOptions?: any;
}
const props = withDefaults(defineProps<QRCodeProps>(), {
	type: "canvas",
	width: 300,
	height: 300,
	margin: 0,
	preview: false,
	qrOptions: {
		typeNumber: 0,
		mode: "Byte",
		errorCorrectionLevel: "Q",
	},
	dotsOptions: { type: "square", color: "#000000" },
	cornersDotOptions: { type: undefined, color: "#000000" },
	cornersSquareOptions: { type: "square", color: "#000000" },
	backgroundOptions: { color: "#ffffff" },
	image: "",
	imageOptions: {
		hideBackgroundDots: true,
		crossOrigin: "anonymous",
		imageSize: 0.4,
		margin: 0,
	},
	fileExt: "png",
	download: false,
	downloadOptions: { name: "haxQRCode", extension: "png" },
});

const qrCode = new QRCodeStyling({
	type: props.type,
	data: props.value,
	width: props.width,
	height: props.height,
	margin: props.margin,
	qrOptions: props.qrOptions,
	dotsOptions: props.dotsOptions,
	cornersDotOptions: props.cornersDotOptions,
	cornersSquareOptions: props.cornersSquareOptions,
	backgroundOptions: props.backgroundOptions,
	image: props.image,
	imageOptions: props.imageOptions,
});

const qrCodeRef = ref<HTMLElement>();
const imageUrl = ref("");
const getImageUrl = async (extension: FileExtension): Promise<string> => {
	if (!qrCode._canvasDrawingPromise) return "";
	const getImageUrl = await qrCode._canvasDrawingPromise;
	if (getImageUrl === undefined) {
		if (!qrCode._canvas) return "";
		return qrCode._canvas.getCanvas().toDataURL(`image/${extension}`);
	}
	return "";
};
const onDownload = () => {
	qrCode.download(props.downloadOptions);
};

onMounted(async () => {
	if (props.type === "canvas" && props.preview) {
		imageUrl.value = await getImageUrl(props.fileExt); // 开启预览，则使用 el-image 展示二维码
	} else {
		qrCode.append(qrCodeRef.value); // 关闭预览，则直接把二维码渲染到 div 上
	}
});
</script>

<style lang="scss" scoped></style>
